 
import { ABaseDecision } from "GameLoop/DecisionMaking/BaseDecision";
import { MainStrategy } from "GameLoop/WorldState/EntityManager/CreateStrategy/MainStrategy";
import { priority } from "utils/constants/definetypes";
import { Roles } from "utils/creep/setups";
import { cpu_used } from "utils/decorate/decorate";
import { PositionHelper } from "utils/position/PositionHelper";
import { generateUniqueId } from "utils/utils";

/**
 * 填充决策。填充 extension tower lab
 */
export class FillDecision< T extends "creep"="creep"> extends ABaseDecision<T>
{
   
    public isExpired(event: IFillStoreEvent, region: string): boolean 
    {
        const taskid =  `${event.region}_fill`;
        const room = Game.rooms[event.region];
        const task = room.findTaskById(taskid,"creep");
        if(task)
        {
            return false;
        }
        return true;
    }
    @cpu_used()
    public makeTask(event: IFillStoreEvent, region: string): IDecisionCode<T>|false
    {
        // global.Log.Info(`维修任务`);
        const room = Game.rooms[event.region];
        const structcache = this.WorldGetter.Station.PollStructure(event.room);

        if(!structcache)
        {
            return false;
        }
        const mineCache = this.WorldGetter.Station.PollSource(event.room);
        if(!mineCache)
        {
            return false;
        }
        const basepos = room.getEntity("SpawnEntity").BasePosition;
        const innerMine = room.getEntitys("InnerMineEntity");
        const spawncenter = PositionHelper.Add(basepos,3,3);
        const filter = (p:RoomPosition)=>
        {
            if(p.distance(spawncenter)<=2)
            {
                return false;
            }
            // for(const e of mineCache.cacheData)

            return true;
        }
       
        const objectfilter = (e:ICacheStructure,radio:number )=>
        {
            const store = Game.getObjectById(e.id) as AnyStoreStructure;
            if(store && store.store.getUsedCapacity(RESOURCE_ENERGY)<store.store.getCapacity(RESOURCE_ENERGY)*radio  )
            {
                // 需要填充
                return true;
            }
            return false
        }
        let fillobjes: ICacheStructure[]=[];
      
        if(event.filltype.includes(STRUCTURE_TOWER))
        {
            const towers = structcache.getStructure(STRUCTURE_TOWER,(e:ICacheStructure)=>objectfilter(e,0.7));
            if(towers)
            {             
                fillobjes = fillobjes.concat(towers);
            }
        }
        if(event.filltype.includes(STRUCTURE_EXTENSION))
        {
           
            const extensions = structcache.getStructure(STRUCTURE_EXTENSION,(e:ICacheStructure)=>objectfilter(e,1)&& filter(e.pos));
            if(extensions)
            {
                fillobjes = fillobjes.concat(extensions);
            }
            
        }
        
        if(event.filltype.includes(STRUCTURE_LAB))
        {
            const labs = structcache.getStructure(STRUCTURE_LAB ,(e:ICacheStructure)=>objectfilter(e,1));
            if(labs)
            {
                fillobjes = fillobjes.concat(labs);
            }
        }
    
        if(fillobjes.length>0)
        {
            const fillTask:ICreepTaskData<"fill"> = 
            {
                type:"fill",
                arg:{
                    targets:fillobjes.map(e=>e.id) as Id<AnyStoreStructure>[]
                },
                room:event.region,
                creeps:[],
                body:{},
                income:-1,
                cost:50,
                required:[
                    [['carry'], fillobjes.length<5?1:2,fillobjes.length<5?1:2]
                ]
            }
            const code:IDecisionCode<T>={
                region:event.region,
                isunique:false,
                task:[{
                    id:`${event.region}_fill`,
                    ttl:5000,
                    priority:priority.S,
                    type:"creep",
                    data:fillTask,
                    shard:10,
                }],
            }
            return code
        }
       

        return false;
    }
    
}